package com.asianrapid.core.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: 迟家鑫
 * @Date: 2018/6/19 13:42
 * @Description: 数据类型转换工具
 */
public class ConvertUtils {

	/**
	 * map转换为bean
	 * Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
	 * @param map 需要转换的map
	 * @param obj 转换成的bean
	 */
	public static void transMap2Bean(Map<String, Object> map, Object obj) {
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (map.containsKey(key)) {
					Object value = map.get(key);
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					setter.invoke(obj, value);
				}
			}
		} catch (Exception e) {
			System.out.println("transMap2Bean Error " + e);
		}
		return;
	}

	/**
	 * bean转换为map
	 * Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
	 * @param obj 需要转换为map的bean
	 * @return map 转换之后的map
	 */
	public static Map<String, Object> transBean2Map(Object obj) {

		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);

					map.put(key, value);
				}
			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}
		return map;
	}

	/**
	 * 将对象强转为字符串
	 * null 和 "" 会返回空字符串（""）
	 * @param obj 需要转换成字符串的对象
	 * @return 转换后的字符串
	 */
	public static String convToString(Object obj) {
		if (obj == null) {
			return "";
		}
		if (StringUtils.isEmpty(obj.toString())) {
			return "";
		}
		return obj.toString();
	}

	/**
	 * 将对象转换值为逻辑值。
	 * null 0 false 空byte[] 为false 其余均为 true
	 * @param obj 需要转换为逻辑值的对象
	 * @return 转换后的逻辑值
	 */
	public static boolean convToBool(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj instanceof byte[]) {
			return convBitToBool((byte[]) obj);
		}
		if ("1".equals(obj.toString())) {
			return true;
		} else if ("0".equals(obj.toString())) {
			return false;
		} else if ("true".equalsIgnoreCase(obj.toString())) {
			return true;
		} else if ("false".equalsIgnoreCase(obj.toString())) {
			return false;
		}
		return false;
	}

	/**
	 * 转换bit为逻辑值。
	 * 数组为null 或者 没有元素 返回false
	 * @param bytes 需要转换的byte[]
	 * @return 转换后的逻辑值
	 */
	public static boolean convBitToBool(byte[] bytes) {
		if (bytes == null) {
			return false;
		}
		return bytes[0] == 0x01 ? true : false;
	}

	/**
	 * 转换值为int型。
	 * 可以将带千位符的数字转换为int类型的数字
	 * 对象为null返回0，如果对象不可以转换为int类型也返回0
	 * @param value 需要转换的对象
	 * @return 转换后的int值
	 */
	public static int convToInt(Object value) {
		int intValue = 0;
		if (value == null) {
			return intValue;
		} else {
			try {
				intValue = Integer.parseInt(value.toString().trim()
						.replace(",", ""));
			} catch (NumberFormatException ex) {
				return intValue;
			}
		}
		return intValue;
	}

	/**
	 * 转换值为long型。
	 * 可以将带千位符的数字转换为long类型的数字
	 * 对象为null返回0，如果对象不可以转换为long类型也返回0
	 * @param value 需要转换的对象
	 * @return 转换后的long值
	 */
	public static long convToLong(Object value) {
		long longValue = 0L;
		if (value == null) {
			return longValue;
		} else {
			try {
				longValue = Long.parseLong(value.toString().trim()
						.replace(",", ""));
			} catch (NumberFormatException ex) {
				return longValue;
			}
		}
		return longValue;
	}

	/**
	 * 转换值为double型。
	 * 可以将带千位符的数字转换为double类型的数字
	 * 对象为null返回0，如果对象不可以转换为double类型也返回0
	 * @param value 需要转换的对象
	 * @return 转换后的double值
	 */
	public static double convToDouble(Object value) {
		double dblValue = 0D;
		if (value == null) {
			return dblValue;
		}
		try {
			dblValue = Double.parseDouble(String.valueOf(value).trim()
					.replace(",", ""));
		} catch (Exception ex) {
			return dblValue;
		}
		return dblValue;
	}


	/**
	 * 将数字格式的字符串转化为传递的对应格式的字符串
	 * 未传递格式，格式为（#,##0.##） 字符串不为数字格式的字符串返回0.00
	 * @param str 需要转换的数字类型的字符串
	 * @return 按照对应格式转换后的数字字符串
	 */
	public static String convToClearZero(String str, String pattern) {
		if(StringUtils.isEmpty(pattern)) {
			pattern = "#,##0.##";
		}
		DecimalFormat df2 = new DecimalFormat(pattern);
		return df2.format(ConvertUtils.convToDouble(str));
	}

	/**
	 * 转换值为BigDecimal型。
	 * 可以将带千位符的数字转换为BigDecimal类型的数字
	 * 对象为null返回0，如果对象不可以转换为BigDecimal类型也返回0
	 * @param value 需要转换的对象
	 * @return 转换后的BigDecimal值
	 */
	public static BigDecimal convToDecimal(Object value) {
		BigDecimal dec = BigDecimal.ZERO;
		if (value == null) {
			return dec;
		} else if (value instanceof BigDecimal) {
			dec = (BigDecimal) value;
		} else {
			try {
				dec = new BigDecimal(String.valueOf(value).trim()
						.replace(",", ""));
			} catch (Exception ex) {
				return dec;
			}
		}
		return dec;
	}

	/**
	 * 将数字格式的字符串转化为金额类型的字符串
	 * eg：将12 变成 12.00
	 * @param value 需要转换的数字格式的字符串
	 * @return 转换后的字符串
	 */
	public static String convToMoney(Object value) {
		return String.format("%1$,.2f", convToDecimal(value));
	}

	/**
	 * 将小数类型的字符串舍弃小数取整数
	 * 如果转换的字符串不是数字类型的字符串，返回0
	 * @param string 需要舍弃小数的小数类型字符串
	 * @return 转换后的整数
	 */
	public static int stringToInt(String string) {
		String str = string.substring(0, string.indexOf("."));
		int intgeo = ConvertUtils.convToInt(str);
		return intgeo;
	}

	/**
	 * 将数字类型的字符串增加千位符
	 *
	 * @param numberStr 需要增加千位符的数字类型的字符串
	 * @return 增加千位符后的字符串
	 */
	public static String fmtMicrometer(String numberStr) {
		DecimalFormat df = null;
		if (numberStr.indexOf(".") > 0) {
			if (numberStr.length() - numberStr.indexOf(".") - 1 == 0) {
				df = new DecimalFormat("###,##0.");
			} else if (numberStr.length() - numberStr.indexOf(".") - 1 == 1) {
				df = new DecimalFormat("###,##0.0");
			} else {
				df = new DecimalFormat("###,##0.00");
			}
		} else {
			df = new DecimalFormat("###,##0");
		}
		double number = 0.0;
		try {
			number = Double.parseDouble(numberStr);
		} catch (Exception e) {
			number = 0.0;
		}
		return df.format(number);
	}

}
